package com.rightsidetech.http.controller.admin.coupon;

import com.gexin.fastjson.JSONArray;
import com.github.pagehelper.PageInfo;
import com.rightsidetech.activity.dto.request.*;
import com.rightsidetech.activity.dto.response.*;
import com.rightsidetech.activity.entity.ActCouponActivity;
import com.rightsidetech.activity.entity.ActCouponActivityStatis;
import com.rightsidetech.activity.service.ActCouponService;
import com.rightsidetech.commom.base.DelReq;
import com.rightsidetech.commom.base.ResponseData;
import com.rightsidetech.commom.enums.CodeIdEnum;
import com.rightsidetech.commom.utils.BeanValidator;
import com.rightsidetech.http.aspect.Auth;
import com.rightsidetech.http.aspect.Log;
import com.rightsidetech.http.aspect.Token;
import com.rightsidetech.http.base.BaseController;
import com.rightsidetech.system.entity.store.SysStoreInfo;
import com.rightsidetech.system.service.SysAgentInfoService;
import com.rightsidetech.system.service.SysCompanyAreaService;
import com.rightsidetech.system.service.SysStoreInfoService;
import com.rightsidetech.system.service.SysUserLoginInfoService;
import com.rightsidetech.trade.dtos.request.TdCouponUsePageReq;
import com.rightsidetech.trade.dtos.response.TdCouponSumAmountStatis;
import com.rightsidetech.trade.dtos.response.TdCouponUsePageResp;
import com.rightsidetech.trade.service.TdCouponUseService;
import com.rightsidetech.trade.service.TdStatisService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shenyu.client.springmvc.annotation.ShenyuSpringMvcClient;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.annotation.Resource;
import javax.validation.ConstraintViolation;
import java.math.BigDecimal;
import java.util.*;

/**
 * @Author: yhr
 * @Date: 2021-12-21 16:17
 */
@RestController
@RequestMapping("/admin/coupon")
@ShenyuSpringMvcClient(path = "/admin/coupon/**")
@Api(tags = "admin:优惠券相关")
public class ActCouponController extends BaseController {
    @Resource
    private ActCouponService actCouponService;
    @Resource
    private SysCompanyAreaService sysCompanyAreaService;
    @Resource
    private TdCouponUseService tdCouponUseService;
    @Resource
    private SysStoreInfoService sysStoreInfoService;
    @Resource
    private SysUserLoginInfoService sysUserLoginInfoService;
    @Resource
    private SysAgentInfoService sysAgentInfoService;
    @Resource
    private TdStatisService tdStatisService;

    @Log
    @Token
    @Auth(bizType = Auth.OPERATOR)
    @GetMapping("/page")
    @ApiOperation("基础优惠券列表")
    public ResponseData<PageInfo<ActCouponBaseResp>> page(ActCouponBasePageReq req){
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        return actCouponService.page(req);

    }

    @Log
    @Token
    @Auth(bizType = Auth.OPERATOR)
    @PostMapping("/save")
    @ApiOperation("新增基础优惠券")
    public ResponseData saveCouponBase(@RequestBody ActCouponBaseSaveReq req) throws Exception{
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        if (req.getCouponType() == 0){
            if (req.getAmount().compareTo(new BigDecimal("10")) > 0){
                return ResponseData.fail("请输入正确的折扣");
            }
        }
        Long loginInfoId = Long.parseLong(getAttribute());
        String loginName = getLoginName();
        return actCouponService.saveCouponBase(req, loginInfoId, loginName);

    }

    @Log
    @Token
    @Auth(bizType = Auth.OPERATOR)
    @PostMapping("/update")
    @ApiOperation("更新基础优惠券")
    public ResponseData updateCouponBase(@RequestBody ActCouponBaseUpdateReq req) throws Exception{
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        Long loginInfoId = Long.parseLong(getAttribute());
        String loginName = getLoginName();
        return actCouponService.updateCouponBase(req,loginInfoId, loginName);

    }

    @Log
    @Token
    @Auth(bizType = Auth.OPERATOR)
    @PostMapping("/del")
    @ApiOperation("删除基础优惠券")
    public ResponseData delCouponSBase(@RequestBody DelReq req) throws Exception{
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        Long loginInfoId = Long.parseLong(getAttribute());
        String loginName = getLoginName();
        return actCouponService.delCouponSBase(req,loginInfoId,loginName);
    }

    @Log
    @Token
    @Auth(bizType = Auth.OPERATOR)
    @GetMapping("/activityPage")
    @ApiOperation("活动优惠券列表")
    public ResponseData<PageInfo<ActCouponActivityPageResp>> activityPage(ActCouponActivityPageReq req){
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        return actCouponService.activityPage(req);

    }

    @Log
    @Token
    @Auth(bizType = Auth.OPERATOR)
    @GetMapping("/activityInfo")
    @ApiOperation("活动优惠券详情")
    public ResponseData<ActCouponActivityInfoResp> activityInfo(Long activityId){
        if (StringUtils.isEmpty(activityId)){
            return ResponseData.fail("优惠券活动id不能为空");
        }
        return actCouponService.activityInfo(activityId);

    }

    @Log
    @Token
    @Auth(bizType = Auth.OPERATOR)
    @PostMapping("/saveActivity")
    @ApiOperation("新增活动优惠券")
    public ResponseData saveActivity(@RequestBody ActCouponActivitySaveReq req) throws Exception {
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        if(req.getTarget() == 0 && (StringUtils.isEmpty(req.getTotalQuantity()) || req.getTotalQuantity() <= 0)){
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), "总数量不能为空");
        }
        List<Long> agentList = findAgentIds(req.getAgentIds(),req.getAreaIds());
        if(agentList.isEmpty()){
            return ResponseData.fail("代理商不能为空");
        }

        req.setUseScope(JSONArray.toJSONString(agentList));
        if(req.getTarget() == 1){
            //统计门店数量
            Long storeNum = sysStoreInfoService.selectCountByAgentId(agentList);
            if(storeNum <= 0){
                return ResponseData.fail("门店数量为空");
            }
            req.setTotalQuantity(storeNum * req.getGetQuantity());
        }

        Long loginInfoId = Long.parseLong(getAttribute());
        String loginName = getLoginName();

        return actCouponService.saveActivity(req,loginInfoId,loginName);
    }

    private List<Long> findAgentIds(String agentIdsStr,String areaIdsStr){
        //查询代理商id数组
        List<Long> agentAllList = new ArrayList<>();
        if(!StringUtils.isEmpty(agentIdsStr)){
            List<Long> agentIds = JSONArray.parseArray(agentIdsStr,Long.class);
            agentAllList.addAll(agentIds);
        }
        if(!StringUtils.isEmpty(areaIdsStr)){
            List<Long> areaIds = JSONArray.parseArray(areaIdsStr,Long.class);
            List<Long> agentIds2 = sysAgentInfoService.findAgentIdsByAreaIds(areaIds);
            if(!agentIds2.isEmpty()){
                agentAllList.addAll(agentIds2);
            }
        }

        Set<Long> agentSet = new HashSet<>(agentAllList);
        agentAllList.clear();
        agentAllList.addAll(agentSet);
        return agentAllList;
    }

    @Log
    @Token
//    @Auth(bizType = Auth.OPERATOR)
    @GetMapping("/saveActivity")
    @ApiOperation("根据代理商数量, 查询优惠券总数量")
    public ResponseData getCouponNum(ActCouponStoreNumReq req){
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        if(req.getAgentIds().isEmpty()){
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), "代理商不能为空");
        }
        List<Long> agentList = req.getAgentIds();
        //统计门店数量
        Long storeNum = sysStoreInfoService.selectCountByAgentId(agentList);
        if(storeNum <= 0){
            return ResponseData.fail("门店数量为空");
        }
        return ResponseData.success(storeNum * req.getGetQuantity());
    }

    @Log
    @Token
    @Auth(bizType = Auth.OPERATOR)
    @PostMapping("/updateActivity")
    @ApiOperation("修改活动优惠券")
    public ResponseData updateActivity(@RequestBody ActCouponActivityUpdateReq req) throws Exception{
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }

        List<Long> agentList = findAgentIds(req.getAgentIds(),req.getAreaIds());
        if(agentList.isEmpty()){
            return ResponseData.fail("代理商不能为空");
        }

        req.setUseScope(JSONArray.toJSONString(agentList));
        if(req.getTarget() == 1){
            //统计门店数量
            Long storeNum = sysStoreInfoService.selectCountByAgentId(agentList);
            if(storeNum <= 0){
                return ResponseData.fail("门店数量为空");
            }
            req.setTotalQuantity(storeNum * req.getGetQuantity());
        }

        Long loginInfoId = Long.parseLong(getAttribute());
        String loginName = getLoginName();
        return actCouponService.updateActivity(req,loginInfoId,loginName);

    }

    @Log
    @Token
    @Auth(bizType = Auth.OPERATOR)
    @PostMapping("/reject")
    @ApiOperation("通过/驳回")
    public ResponseData reject(@RequestBody ActCouponActivityStatusReq req) throws Exception{
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        Long loginInfoId = Long.parseLong(getAttribute());
        String loginName = getLoginName();

        return actCouponService.reject(req,loginInfoId,loginName);

    }

    @Log
    @Token
    @Auth(bizType = Auth.OPERATOR)
    @PostMapping("/check")
    @ApiOperation("提交审核")
    public ResponseData check(@RequestBody DelReq req) throws Exception{
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        Long loginInfoId = Long.parseLong(getAttribute());
        String loginName = getLoginName();
        return actCouponService.check(req.getId(),loginInfoId,loginName);

    }

    @Log
    @Token
    @Auth(bizType = Auth.OPERATOR)
    @PostMapping("/delActivity")
    @ApiOperation("删除优惠券活动")
    public ResponseData del(@RequestBody DelReq req) throws Exception{
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        Long loginInfoId = Long.parseLong(getAttribute());
        String loginName = getLoginName();
        return actCouponService.delActivity(req.getId(),loginInfoId,loginName);

    }

    @Log
    @Token
    @Auth(bizType = Auth.OPERATOR)
    @PostMapping("/generate")
    @ApiOperation("生成优惠券")
    public ResponseData generate(@RequestBody DelReq req) throws Exception{
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }

/*        ActCouponActivity actCouponActivity = actCouponService.getActivityByActivityId(req.getId());
        if(StringUtils.isEmpty(actCouponActivity)){
            return ResponseData.fail("活动不存在");
        }
        String useScope = actCouponActivity.getUseScope();
        if(StringUtils.isEmpty(useScope)){
            return ResponseData.fail("范围不能为空");
        }*/

/*        List<Long> agentList = JSONArray.parseArray(useScope,Long.class);
        //统计门店数量
        Long storeNum = sysStoreInfoService.selectCountByAgentId(agentList);
        if(storeNum <= 0){
            return ResponseData.fail("门店数量为空");
        }*/
        Long loginInfoId = Long.parseLong(getAttribute());
        String loginName = getLoginName();

        return actCouponService.generate(req.getId(),loginInfoId,loginName);

    }

//    @Log
//    @Token
//    @Auth(bizType = Auth.OPERATOR)
//    @GetMapping("/getRegion")
//    @ApiOperation("区域列表")
//    public ResponseData getRegion(RegionTreeReq req){
//        ConstraintViolation validate = BeanValidator.validate(req);
//        if (validate != null) {
//            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
//        }
//        return sysCompanyAreaService.getRegionTree(req);
//
//    }

    @Log
    @Token
    @Auth(bizType = Auth.OPERATOR)
    @GetMapping("/userCoupon")
    @ApiOperation("用户优惠券")
    @ApiIgnore
    public ResponseData<PageInfo<ActUserGetCouponResp>> userCoupon(ActUserCouponReq req){
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        return actCouponService.selectUserCoupon(req);

    }

    @Log
    @Token
    @Auth(bizType = Auth.OPERATOR)
    @GetMapping("/entityCoupon")
    @ApiOperation("实体优惠券")
    public ResponseData<PageInfo<ActEntityCouponResp>> getEntityCoupon(ActEntityCouponReq req){
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        return actCouponService.selectEntityCoupon(req);
    }


    @Log
    @Token
    @Auth(bizType = Auth.OPERATOR)
    @GetMapping("/storeCoupon")
    @ApiOperation("门店优惠券")
    @ApiIgnore
    public ResponseData<PageInfo<ActUserCouponResp>> storeCoupon(ActUserCouponReq req){
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        ResponseData<PageInfo<ActUserCouponResp>> responseData = actCouponService.selectStoreCoupon(req);
        if (responseData.getCodeId() == 1){
            for (ActUserCouponResp resp:responseData.getResData().getList()) {
                SysStoreInfo sysStoreInfo = sysStoreInfoService.selectByPrimaryKey(resp.getStoreId());
                if (!ObjectUtils.isEmpty(sysStoreInfo)){
                    resp.setStoreName(sysStoreInfo.getStoreName());
                }
            }
        }
        return responseData;

    }

    @Log
    @Token
    @Auth(bizType = Auth.OPERATOR)
    @GetMapping("/receivePage")
    @ApiOperation("优惠券领取记录")
    public ResponseData<PageInfo<ActReceivePageResp>> receivePage(ActUserCouponReq req){
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        return actCouponService.receivePage(req);
    }

    @Log
    @Token
    @Auth(bizType = Auth.OPERATOR)
    @GetMapping("/usePage")
    @ApiOperation("优惠券使用记录")
    public ResponseData<PageInfo<TdCouponUsePageResp>> usePage(TdCouponUsePageReq req){
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        return tdCouponUseService.couponUsePage(req);
    }

    @Log
    @Token
    @Auth(bizType = Auth.OPERATOR)
    @GetMapping("/couponCount")
    @ApiOperation("优惠券统计")
    public ResponseData<PageInfo<ActCouponCountPageResp>> couponCount(ActCouponCountReq req){
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        return actCouponService.couponCount(req);
    }

    @Log
    @Token
    @Auth(bizType = Auth.OPERATOR)
    @PostMapping("/close")
    @ApiOperation("作废")
    public ResponseData couponCount(@RequestBody DelReq req) throws Exception{
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        Long loginInfoId = Long.parseLong(getAttribute());
        String loginName = getLoginName();
        ResponseData resp = actCouponService.couponClose(req.getId(), loginInfoId, loginName);

        if(resp.getCodeId() == 1){
            statisActCoupon(req.getId());
        }

        return resp;
    }

    private ResponseData statisActCoupon(Long activityId2){
        List<Long> activityList = new ArrayList<>();
        //判断是否传入优惠券id

        activityList.add(activityId2);


        if(activityList.isEmpty()){
            return ResponseData.fail("没有找到可以统计的优惠活动");
        }

        for(Long activityId:activityList){
            ActCouponActivityStatis statis = new ActCouponActivityStatis();
            //统计优惠券活动
            ActCouponActivity activity2 = actCouponService.getActivityByActivityId(activityId);
            //查找已被使用的优惠券
            Long getCountNum = actCouponService.findCountByActivityId(activityId,(byte) 0);
            //已使用的优惠券
            Long usedCountNum = actCouponService.findCountByActivityId(activityId,(byte) 1);
            //统计金额
            TdCouponSumAmountStatis amountStatis = tdStatisService.statisTotalAmountByActivityId(activityId);

            statis.setReceiveNum(getCountNum + usedCountNum);
            statis.setUseNum(usedCountNum);
            statis.setCouponActivityId(activityId);
            statis.setQuantity(activity2.getTotalQuantity());
            statis.setStatisAt(new Date());
            statis.setTotalPayableAmount(amountStatis.getTotalAmount());
            statis.setTotalPayAmount(amountStatis.getActualAmount());
            statis.setTotalDiscountAmount(amountStatis.getDiscountAmount());

            actCouponService.saveActivityStatis(statis);
        }

        return ResponseData.success();
    }
}
